package com.huaxonline.sign.sdk.examples;

import com.huaxonline.sign.sdk.SignClient;
import com.huaxonline.sign.sdk.SignUtil;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 客户端使用示例
 * 展示如何在实际项目中使用签名SDK
 * 
 * @author zhaoshulei
 * @since 2023/9/13
 */
public class ClientExamples {
    
    // 配置信息
    private static final String APP_ID = "test_app";
    private static final String SECRET = "test_secret_123456";
    private static final String BASE_URL = "http://localhost:8080/api";
    
    public static void main(String[] args) {
        // 示例1: 用户管理API
        userManagementExample();
        
        // 示例2: 订单管理API
        orderManagementExample();
        
        // 示例3: 文件上传API
        fileUploadExample();
        
        // 示例4: 批量操作API
        batchOperationExample();
        
        // 示例5: 错误处理和重试
        errorHandlingExample();
    }
    
    /**
     * 用户管理API示例
     */
    public static void userManagementExample() {
        System.out.println("=== 用户管理API示例 ===");
        
        SignClient client = new SignClient(APP_ID, SECRET);
        
        try {
            // 1. 查询用户列表
            Map<String, Object> queryParams = new HashMap<>();
            queryParams.put("page", 1);
            queryParams.put("size", 10);
            queryParams.put("status", "active");
            
            SignClient.HttpResponse response = client.sendGet(BASE_URL + "/users", queryParams);
            System.out.println("查询用户列表: " + response.getStatusCode() + " - " + response.getBody());
            
            // 2. 创建用户
            Map<String, Object> userData = new HashMap<>();
            userData.put("name", "张三");
            userData.put("email", "zhangsan@example.com");
            userData.put("phone", "13800138000");
            userData.put("age", 25);
            
            response = client.sendPostJson(BASE_URL + "/users", userData);
            System.out.println("创建用户: " + response.getStatusCode() + " - " + response.getBody());
            
            // 3. 更新用户信息
            Map<String, Object> updateData = new HashMap<>();
            updateData.put("name", "张三（更新）");
            updateData.put("age", 26);
            
            response = client.sendPostJson(BASE_URL + "/users/123", updateData);
            System.out.println("更新用户: " + response.getStatusCode() + " - " + response.getBody());
            
            // 4. 删除用户
            Map<String, Object> deleteParams = new HashMap<>();
            deleteParams.put("userId", "123");
            
            response = client.sendGet(BASE_URL + "/users/123/delete", deleteParams);
            System.out.println("删除用户: " + response.getStatusCode() + " - " + response.getBody());
            
        } catch (IOException e) {
            System.err.println("用户管理API调用失败: " + e.getMessage());
        }
    }
    
    /**
     * 订单管理API示例
     */
    public static void orderManagementExample() {
        System.out.println("\n=== 订单管理API示例 ===");
        
        SignClient client = new SignClient(APP_ID, SECRET, SignClient.SignAlgorithm.HMAC_SHA256);
        
        try {
            // 1. 创建订单
            Map<String, Object> orderData = new HashMap<>();
            orderData.put("userId", "12345");
            orderData.put("productId", "PROD001");
            orderData.put("quantity", 2);
            orderData.put("price", 99.99);
            orderData.put("address", "北京市朝阳区");
            orderData.put("phone", "13800138000");
            
            SignClient.HttpResponse response = client.sendPostJson(BASE_URL + "/orders", orderData);
            System.out.println("创建订单: " + response.getStatusCode() + " - " + response.getBody());
            
            // 2. 查询订单列表
            Map<String, Object> queryParams = new HashMap<>();
            queryParams.put("userId", "12345");
            queryParams.put("status", "pending");
            queryParams.put("page", 1);
            queryParams.put("size", 20);
            
            response = client.sendGet(BASE_URL + "/orders", queryParams);
            System.out.println("查询订单列表: " + response.getStatusCode() + " - " + response.getBody());
            
            // 3. 查询订单详情
            Map<String, Object> detailParams = new HashMap<>();
            detailParams.put("orderId", "ORDER123456");
            
            response = client.sendGet(BASE_URL + "/orders/ORDER123456", detailParams);
            System.out.println("查询订单详情: " + response.getStatusCode() + " - " + response.getBody());
            
            // 4. 更新订单状态
            Map<String, Object> statusData = new HashMap<>();
            statusData.put("status", "shipped");
            statusData.put("trackingNumber", "SF1234567890");
            statusData.put("remark", "已发货");
            
            response = client.sendPostJson(BASE_URL + "/orders/ORDER123456/status", statusData);
            System.out.println("更新订单状态: " + response.getStatusCode() + " - " + response.getBody());
            
            // 5. 取消订单
            Map<String, Object> cancelData = new HashMap<>();
            cancelData.put("reason", "用户取消");
            cancelData.put("remark", "联系用户确认");
            
            response = client.sendPostJson(BASE_URL + "/orders/ORDER123456/cancel", cancelData);
            System.out.println("取消订单: " + response.getStatusCode() + " - " + response.getBody());
            
        } catch (IOException e) {
            System.err.println("订单管理API调用失败: " + e.getMessage());
        }
    }
    
    /**
     * 文件上传API示例
     */
    public static void fileUploadExample() {
        System.out.println("\n=== 文件上传API示例 ===");
        
        SignClient client = new SignClient(APP_ID, SECRET);
        
        try {
            // 1. 上传文本文件
            Map<String, Object> uploadParams = new HashMap<>();
            uploadParams.put("fileName", "test.txt");
            uploadParams.put("fileType", "text/plain");
            uploadParams.put("fileSize", 1024);
            
            String fileContent = "这是测试文件内容\n包含多行文本\n用于测试文件上传功能";
            
            SignClient.HttpResponse response = client.sendPost(BASE_URL + "/files/upload", uploadParams, fileContent);
            System.out.println("上传文本文件: " + response.getStatusCode() + " - " + response.getBody());
            
            // 2. 上传JSON文件
            Map<String, Object> jsonParams = new HashMap<>();
            jsonParams.put("fileName", "config.json");
            jsonParams.put("fileType", "application/json");
            
            String jsonContent = "{\n" +
                    "  \"appName\": \"测试应用\",\n" +
                    "  \"version\": \"1.0.0\",\n" +
                    "  \"config\": {\n" +
                    "    \"debug\": true,\n" +
                    "    \"timeout\": 30000\n" +
                    "  }\n" +
                    "}";
            
            response = client.sendPost(BASE_URL + "/files/upload", jsonParams, jsonContent);
            System.out.println("上传JSON文件: " + response.getStatusCode() + " - " + response.getBody());
            
            // 3. 查询文件列表
            Map<String, Object> listParams = new HashMap<>();
            listParams.put("userId", "12345");
            listParams.put("fileType", "text/plain");
            listParams.put("page", 1);
            listParams.put("size", 10);
            
            response = client.sendGet(BASE_URL + "/files", listParams);
            System.out.println("查询文件列表: " + response.getStatusCode() + " - " + response.getBody());
            
            // 4. 下载文件
            Map<String, Object> downloadParams = new HashMap<>();
            downloadParams.put("fileId", "FILE123456");
            
            response = client.sendGet(BASE_URL + "/files/FILE123456/download", downloadParams);
            System.out.println("下载文件: " + response.getStatusCode() + " - " + response.getBody());
            
        } catch (IOException e) {
            System.err.println("文件上传API调用失败: " + e.getMessage());
        }
    }
    
    /**
     * 批量操作API示例
     */
    public static void batchOperationExample() {
        System.out.println("\n=== 批量操作API示例 ===");
        
        SignClient client = new SignClient(APP_ID, SECRET);
        
        try {
            // 1. 批量创建用户
            Map<String, Object> batchData = new HashMap<>();
            batchData.put("users", new Object[]{
                createUserMap("用户1", "user1@example.com", 25),
                createUserMap("用户2", "user2@example.com", 30),
                createUserMap("用户3", "user3@example.com", 28)
            });
            
            SignClient.HttpResponse response = client.sendPostJson(BASE_URL + "/users/batch", batchData);
            System.out.println("批量创建用户: " + response.getStatusCode() + " - " + response.getBody());
            
            // 2. 批量更新订单状态
            Map<String, Object> batchUpdateData = new HashMap<>();
            batchUpdateData.put("orders", new Object[]{
                createOrderMap("ORDER001", "shipped"),
                createOrderMap("ORDER002", "delivered"),
                createOrderMap("ORDER003", "completed")
            });
            
            response = client.sendPostJson(BASE_URL + "/orders/batch/status", batchUpdateData);
            System.out.println("批量更新订单状态: " + response.getStatusCode() + " - " + response.getBody());
            
            // 3. 批量删除文件
            Map<String, Object> batchDeleteData = new HashMap<>();
            batchDeleteData.put("fileIds", new String[]{"FILE001", "FILE002", "FILE003"});
            batchDeleteData.put("reason", "批量清理");
            
            response = client.sendPostJson(BASE_URL + "/files/batch/delete", batchDeleteData);
            System.out.println("批量删除文件: " + response.getStatusCode() + " - " + response.getBody());
            
        } catch (IOException e) {
            System.err.println("批量操作API调用失败: " + e.getMessage());
        }
    }
    
    /**
     * 错误处理和重试示例
     */
    public static void errorHandlingExample() {
        System.out.println("\n=== 错误处理和重试示例 ===");
        
        SignClient client = new SignClient(APP_ID, SECRET);
        
        // 示例1: 处理网络超时
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("test", "timeout");
            
            SignClient.HttpResponse response = client.sendGet("http://slow-api.example.com/timeout", params);
            System.out.println("超时测试: " + response.getStatusCode());
        } catch (IOException e) {
            System.err.println("网络超时: " + e.getMessage());
        }
        
        // 示例2: 处理签名错误
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("test", "signature_error");
            
            SignClient.HttpResponse response = client.sendGet(BASE_URL + "/test/signature-error", params);
            if (response.getStatusCode() == 401) {
                System.out.println("签名验证失败: " + response.getBody());
            }
        } catch (IOException e) {
            System.err.println("签名错误: " + e.getMessage());
        }
        
        // 示例3: 重试机制
        int maxRetries = 3;
        int retryCount = 0;
        
        while (retryCount < maxRetries) {
            try {
                Map<String, Object> params = new HashMap<>();
                params.put("test", "retry");
                
                SignClient.HttpResponse response = client.sendGet(BASE_URL + "/test/retry", params);
                if (response.isSuccess()) {
                    System.out.println("重试成功: " + response.getBody());
                    break;
                } else {
                    System.out.println("重试失败: " + response.getStatusCode());
                }
            } catch (IOException e) {
                System.err.println("重试异常: " + e.getMessage());
            }
            
            retryCount++;
            if (retryCount < maxRetries) {
                try {
                    Thread.sleep(1000 * retryCount); // 递增等待时间
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }
        
        if (retryCount >= maxRetries) {
            System.err.println("重试次数已达上限，操作失败");
        }
    }
    
    /**
     * 高级用法示例
     */
    public static void advancedUsageExample() {
        System.out.println("\n=== 高级用法示例 ===");
        
        // 1. 使用工具类快速构建参数
        Map<String, Object> params = SignUtil.createParamsWithTimestamp();
        SignUtil.addParam(params, "userId", "12345");
        SignUtil.addParam(params, "action", "query");
        
        // 2. 生成签名
        String signature = SignUtil.quickSign(APP_ID, SECRET, params);
        System.out.println("快速签名: " + signature);
        
        // 3. 验证参数
        boolean isValid = SignUtil.validateSignParams(params);
        System.out.println("参数验证: " + isValid);
        
        // 4. 提取签名参数
        SignClient.SignParams signParams = SignUtil.extractSignParams(params);
        System.out.println("签名参数: " + signParams.getAppId() + " - " + signParams.getTimestamp());
        
        // 5. 安全获取参数
        String userId = SignUtil.getStringParam(params, "userId", "unknown");
        Integer age = SignUtil.getIntParam(params, "age", 0);
        System.out.println("安全获取参数 - userId: " + userId + ", age: " + age);
        
        // 6. 创建自定义配置的客户端
        SignClient customClient = new SignClient(
            APP_ID, 
            SECRET, 
            SignClient.SignAlgorithm.HMAC_SHA256, 
            1800000L, // 30分钟时间容差
            true      // 启用调试模式
        );
        
        try {
            Map<String, Object> testParams = new HashMap<>();
            testParams.put("test", "custom_client");
            
            SignClient.HttpResponse response = customClient.sendGet(BASE_URL + "/test/custom", testParams);
            System.out.println("自定义客户端响应: " + response.getStatusCode() + " - " + response.getBody());
        } catch (IOException e) {
            System.err.println("自定义客户端调用失败: " + e.getMessage());
        }
    }
    
    /**
     * 创建用户Map对象（Java 8兼容）
     */
    private static Map<String, Object> createUserMap(String name, String email, int age) {
        Map<String, Object> userMap = new HashMap<>();
        userMap.put("name", name);
        userMap.put("email", email);
        userMap.put("age", age);
        return userMap;
    }
    
    /**
     * 创建订单Map对象（Java 8兼容）
     */
    private static Map<String, Object> createOrderMap(String orderId, String status) {
        Map<String, Object> orderMap = new HashMap<>();
        orderMap.put("orderId", orderId);
        orderMap.put("status", status);
        return orderMap;
    }
}